unit SimulationForm;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, ToolWin, Menus, ImgList, PngImageList, ExtCtrls, PendulumView,
  StdCtrls, PendulumGraph, OleCtrls, SHDocVw, SimulationData, Pendulum, SimulationEngine, 
  Math, PendulumViewUtils, WebConsts ;

type


  TSimulationForm = class(TForm)
    ToolBar1: TToolBar;
    StatusBar1: TStatusBar;
    PngImageList1: TPngImageList;
    tbtnPlaySim: TToolButton;
    tbtnStopSim: TToolButton;
    tbtnResetSim: TToolButton;
    ToolButton6: TToolButton;
    tbtnSettingsPane: TToolButton;
    ToolButton8: TToolButton;
    tbtnHelp: TToolButton;
    Splitter1: TSplitter;
    Panel1: TPanel;
    Label1: TLabel;
    PendulumView1: TPendulumView;
    Panel2: TPanel;
    SettingsPageControl: TPageControl;
    tsSimSettings: TTabSheet;
    tsPendProps: TTabSheet;
    Splitter2: TSplitter;
    Panel3: TPanel;
    Splitter3: TSplitter;
    Panel4: TPanel;
    Panel5: TPanel;
    Label2: TLabel;
    InclinationGraph: TPendulumGraph;
    AngularVelocityGraph: TPendulumGraph;
    Label4: TLabel;
    Splitter5: TSplitter;
    PngImageList2: TPngImageList;
    tsViewProps: TTabSheet;
    tsAbout: TTabSheet;
    Label5: TLabel;
    edSimLength: TEdit;
    Label6: TLabel;
    chkRunUntil: TCheckBox;
    Label7: TLabel;
    edSimTimeStep: TEdit;
    Label8: TLabel;
    Label9: TLabel;
    edGravity: TEdit;
    Label10: TLabel;
    Label11: TLabel;
    edStringLength: TEdit;
    Label12: TLabel;
    Label13: TLabel;
    edBobMass: TEdit;
    Label14: TLabel;
    Label15: TLabel;
    edDampingFactor: TEdit;
    Label16: TLabel;
    Button1: TButton;
    Button2: TButton;
    Label18: TLabel;
    edDataPlotPer: TEdit;
    Label19: TLabel;
    lblDataPoints: TLabel;
    Label21: TLabel;
    Label22: TLabel;
    Label23: TLabel;
    Label24: TLabel;
    Label25: TLabel;
    Label26: TLabel;
    Label27: TLabel;
    Label28: TLabel;
    Label29: TLabel;
    Label30: TLabel;
    Label31: TLabel;
    Label32: TLabel;
    Label33: TLabel;
    edRefreshRate: TEdit;
    Label34: TLabel;
    paintClock: TTimer;
    simulationClock: TTimer;
    TrackBar1: TTrackBar;
    Label35: TLabel;
    Label36: TLabel;
    Label37: TLabel;
    Label20: TLabel;
    edInclination: TEdit;
    Label38: TLabel;
    Label39: TLabel;
    edAngularVelocity: TEdit;
    Label40: TLabel;
    tbtnUpdate: TToolButton;
    Button3: TButton;
    Label17: TLabel;
    Label3: TLabel;
    chkDamping: TCheckBox;
    ToolBar2: TToolBar;
    tbtnBack: TToolButton;
    tbtnForward: TToolButton;
    ToolButton3: TToolButton;
    tbtnHome: TToolButton;
    ToolButton5: TToolButton;
    tbnQuickHelp: TToolButton;
    WebBrowser1: TWebBrowser;
    procedure TrackBar1Change(Sender: TObject);
    procedure SettingsPageControlChanging(Sender: TObject;
      var AllowChange: Boolean);
    procedure FormCreate(Sender: TObject);
	procedure tbtnStopSimClick(Sender: TObject);
    procedure tbtnResetSimClick(Sender: TObject);
	procedure tbtnPlaySimClick(Sender: TObject);
    procedure tbtnSettingsPaneClick(Sender: TObject);
    procedure tbtnUpdateClick(Sender: TObject);
    //procedure tbtnPlaySimClick(Sender: TObject);
    procedure paintClockTimer(Sender: TObject);
    procedure simulationClockTimer(Sender: TObject);
    procedure Label3Click(Sender: TObject);
    procedure Label4Click(Sender: TObject);
    procedure Label2Click(Sender: TObject);
    procedure PendulumView1RequestPause(Sender: TObject);
    procedure PendulumView1AngleChanged(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure RunSimulation1Click(Sender: TObject);
    procedure PauseSimulation1Click(Sender: TObject);
    procedure ResetSimulation1Click(Sender: TObject);
    procedure SimulationSettings1Click(Sender: TObject);
    procedure edInclinationChange(Sender: TObject);
    procedure edDampingFactorMouseMove(Sender: TObject; Shift: TShiftState;
      X, Y: Integer);
    procedure edStringLengthMouseMove(Sender: TObject; Shift: TShiftState;
      X, Y: Integer);
    procedure chkDampingMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure edGravityMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure edSimTimeStepMouseMove(Sender: TObject; Shift: TShiftState;
      X, Y: Integer);
    procedure edBobMassMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure edInclinationMouseMove(Sender: TObject; Shift: TShiftState;
      X, Y: Integer);
    procedure edAngularVelocityMouseMove(Sender: TObject;
      Shift: TShiftState; X, Y: Integer);
    procedure edRefreshRateMouseMove(Sender: TObject; Shift: TShiftState;
      X, Y: Integer);
    procedure Button1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure Button2MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure PendulumView1MouseMove(Sender: TObject; Shift: TShiftState;
      X, Y: Integer);
    procedure Button2Click(Sender: TObject);
    procedure tbtnHelpClick(Sender: TObject);
    procedure tbtnBackClick(Sender: TObject);
    procedure tbtnHomeClick(Sender: TObject);
    procedure InclinationGraphWhatsThis(Sender: TObject);
    procedure AngularVelocityGraphWhatsThis(Sender: TObject);
    procedure Help2Click(Sender: TObject);
    procedure Exit1Click(Sender: TObject);
    procedure Close1Click(Sender: TObject);
    procedure tbtnNewClick(Sender: TObject);
    procedure NewSimulation1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure edSimTimeStepChange(Sender: TObject);
    procedure edGravityChange(Sender: TObject);
    procedure edStringLengthChange(Sender: TObject);
    procedure edBobMassChange(Sender: TObject);
    procedure edDampingFactorChange(Sender: TObject);
    procedure chkDampingClick(Sender: TObject);
    procedure edRefreshRateChange(Sender: TObject);
    procedure tbnQuickHelpClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
	_pendulum : TPendulum; //local pendulum
	_localSim : TPendulumSim; //local pendulum simulator
	_currentStep : TSimData;
    _dataPlotPer : Integer;
	
	//Paused?
	_paused : boolean;
	
	//Maximum iter count when determining optimum scales
	_scalingIterCount : integer;

	//Settings Pane
    procedure UpdateBoxes; //Updates the edit boxes in the settings pane with updated values
	function CommitSimSettings : boolean; //Commits changes from SimSettings
	function CommitPendulumProps: boolean; //Commits changes from PendulumProps
	function CommitViewProps: boolean; //Commits changes from ViewProps
	procedure CalculateOptimumScales;
	
	function GetAppPath: String;
	
  public
    { Public declarations }
	procedure SetPaused; //Function sets the form to pause mode
	procedure PlaySim; //Procedure sets the form to run mode

  end;

   var
   mSimulationForm: TSimulationForm;


implementation

{$R *.DFM} {$R Project.res}

procedure TSimulationForm.TrackBar1Change(Sender: TObject);
begin
edDampingFactor.Text := floatToStr(TrackBar1.Position/20);
end;

//Update variables when we change the page of the settings page control
procedure TSimulationForm.SettingsPageControlChanging(Sender: TObject;
  var AllowChange: Boolean);
begin
 case SettingsPageControl.ActivePageIndex of
	0: //Simulation Settings Page
	begin
		AllowChange := CommitSimSettings;
	end;
	1: //Pendulum Properties Page
	begin
		AllowChange := CommitPendulumProps;
	end;
	2: //View Properties Page
	begin
		AllowChange := CommitViewProps;
	end;
 end;
 
end;

function TSimulationForm.CommitSimSettings : boolean;
var mbResult : integer;
begin
	try
	_localSim.Length := strToFloat(edSimLength.Text);
	_localSim.TimeStep := strToFloat(edSimTimeStep.Text)/1000;
	simulationClock.Interval := round(_localSim.TimeStep*1000);
	_localSim.Gravity := strToFloat(edGravity.Text);
	_localSim.DampingEnabled := chkDamping.Checked;
	//UpdateBoxes;
	except
		on E:Exception do
		begin
			mbResult := Application.MessageBox(PChar('Description: '+E.Message+#13#10+'Settings will be discarded!'), PChar('Exception Raised: '+E.ClassName), MB_RETRYCANCEL+MB_ICONEXCLAMATION);
			if mbResult = IDRETRY then
			CommitSimSettings := false
			else
			begin
			UpdateBoxes;
			CommitSimSettings := true;
			end;
		end;
	end;
end;

function TSimulationForm.CommitPendulumProps : boolean;
var mbResult : integer;
begin
	try
	_pendulum.StringLength := strToFloat(edStringLength.Text);
	_pendulum.BobMass := strToFloat(edBobMass.Text)/1000;
	_localSim.DampingFactor := strToFloat(edDampingFactor.Text);
	//UpdateBoxes;
	except
		on E:Exception do
		begin
			mbResult := Application.MessageBox(PChar('Description: '+E.Message+#13#10+'Settings will be discarded!'), PChar('Exception Raised: '+E.ClassName), MB_RETRYCANCEL+MB_ICONEXCLAMATION);
			if mbResult = IDRETRY then
			CommitPendulumProps := false
			else
			begin
			UpdateBoxes;
			CommitPendulumProps := true;
			end;
		end;
	end;
end;

function TSimulationForm.CommitViewProps : boolean;
var mbResult : integer;
begin
	try
	_dataPlotPer := strToInt(edDataPlotPer.Text);
        PaintClock.Enabled := false;
	PaintClock.Interval := round(1000/strToFloat(edRefreshRate.Text));
        PaintClock.Enabled := true;

	//UpdateBoxes;
	except
		on E:Exception do
		begin
			mbResult := Application.MessageBox(PChar('Description: '+E.Message+#13#10+'Settings will be discarded!'), PChar('Exception Raised: '+E.ClassName), MB_RETRYCANCEL+MB_ICONEXCLAMATION);
			if mbResult = IDRETRY then
			CommitViewProps := false
			else
			begin
			UpdateBoxes;
			CommitViewProps := true;
			end;
		end;
	end;
end;



procedure TSimulationForm.UpdateBoxes;
begin

	//Simulation Settings Page
	edSimLength.Text := floatToStr(_localSim.Length);
	edSimTimeStep.Text := floatToStr(_localSim.TimeStep*1000);
	edGravity.Text := floatToStr(_localSim.Gravity);
	chkDamping.Checked := _localSim.DampingEnabled;
	
	//Pendulum properties page
	edStringLength.Text := floatToStr(_pendulum.StringLength);
	edBobMass.Text := floatToStr(_pendulum.BobMass*1000);
	edDampingFactor.Text := floatToStr(_localSim.DampingFactor);
	TrackBar1.Position := min(20,round(_localSim.DampingFactor*20));
        edInclination.Text := rad2degRS(PendulumView1.Angle);
	edAngularVelocity.Text := floatToStr(_localSim.CurrentStep.AngularVelocity);
	//View properties
	edDataPlotPer.Text := intToStr(_dataPlotPer);
	edRefreshRate.Text := floatToStr(round(1000/PaintClock.Interval));
	lblDataPoints.Caption := '('+floatToStr(_dataPlotPer*_localSim.TimeStep*1000)+'ms)';
	
end;
procedure TSimulationForm.FormCreate(Sender: TObject);
begin
	//Disable our clock
	
	simulationClock.Enabled := false;
	
	paintClock.Enabled := true;
	_pendulum := TPendulum.Create(1.0, 0.1, 0.0025);
	_localSim := TPendulumSim.Create(10, 0.04, 9.81, pi/4, 0,_pendulum, psmLive);
    simulationClock.Interval := 40;
	paintClock.Interval := 44;
	_dataPlotPer := 1;
	
	SetPaused; //Pause the sim
	
	//Set the initial state for the settings page control
	SettingsPageControl.Visible := true;
	tbtnSettingsPane.Down := SettingsPageControl.Visible;
	
	//Set the scale for each graph box
	InclinationGraph.SetScale(10,1);
	AngularVelocityGraph.SetScale(10,10);
	//EnergyGraph.SetScale(10,1);
	
	//Initialise the graph boxes;
	InclinationGraph.Initialise;
	AngularVelocityGraph.Initialise;
	//EnergyGraph.Initialise;
	
	_scalingIterCount := 1000;
	CalculateOptimumScales;

        tbtnHomeClick(Sender);
	UpdateBoxes;
	
	
end;

procedure TSimulationForm.SetPaused;
begin
	//Disable the simulation clock;
	simulationClock.Enabled := false;

	//Set the pendulum views IsPaused property;
	pendulumView1.IsPaused := true;
	
	//Depress the play button
	tbtnPlaySim.Down := false;
	
	//Press the pause button
	tbtnStopSim.Down := true;
	
	//Set the status bar text
	StatusBar1.Panels[0].Text := 'Simulation : Paused';
	
	//Set the forms paused variable
	_paused := true;
end;


procedure TSimulationForm.tbtnStopSimClick(Sender: TObject);
var mbReply : integer;
begin
	if not _paused then
	begin
        SetPaused;
		//Ask the user whether to pause
		mbReply := Application.MessageBox('Are you sure you want to pause this simulation?', 'PendulumSimulator', MB_ICONEXCLAMATION+MB_YESNO);
		if mbReply = IDNO then
		PlaySim;
	end
	else
	begin
		SetPaused; //Just for the heck of it
	end;
end;

procedure TSimulationForm.tbtnResetSimClick(Sender: TObject);
var mbResult :integer;
begin
	//Call the local sims reset method
	try
	_localSim.Reset(deg2rad(strToFloat(edInclination.Text)), strToFloat(edAngularVelocity.Text));
        PendulumView1.Angle := deg2rad(strToFloat(edInclination.Text));
        PendulumView1.AngularVelocity := strToFloat(edAngularVelocity.Text);
	except
		on E: Exception do
		begin
			mbResult := Application.MessageBox(PChar('Description: '+E.Message), PChar('Exception Raised: '+E.ClassName), MB_OK+MB_ICONEXCLAMATION);
		end;
	end;
	InclinationGraph.Initialise;
	AngularVelocityGraph.Initialise;



        StatusBar1.Panels[0].Text := 'Simulation Reset';
        CalculateOptimumScales;
end;

procedure TSimulationForm.tbtnSettingsPaneClick(Sender: TObject);
begin
	//Toggle the settings pane visible or not
	SettingsPageControl.Visible := not SettingsPageControl.Visible;
	tbtnSettingsPane.Down := SettingsPageControl.Visible;
end;

procedure TSimulationForm.tbtnUpdateClick(Sender: TObject);
begin
CommitSimSettings;
CommitPendulumProps;
CommitViewProps;
 UpdateBoxes
end;

procedure TSimulationForm.tbtnPlaySimClick(Sender: TObject);
begin
	if _paused then
	begin
		PlaySim;
	end
	else tbtnPlaySim.Down := true;
	
end;

procedure TSimulationForm.PlaySim;
begin
	//Enable the pendulumView
	pendulumView1.IsPaused := false;
	
	//Press the play button
	tbtnPlaySim.Down := true;
	
	//depress the pause button
	tbtnStopSim.Down := false;
	
	//Set the status bar text
	StatusBar1.Panels[0].Text := 'Simulation : Running';
	
	//Set the forms paused variable
	_paused := false;
	
	//Enabled the simulation clock
	simulationClock.Enabled := true;
end;

procedure TSimulationForm.paintClockTimer(Sender: TObject);
begin
pendulumView1.Paint;
if InclinationGraph.Visible then InclinationGraph.Paint;
if AngularVelocityGraph.Visible then AngularVelocityGraph.Paint;
//if EnergyGraph.Visible then //EnergyGraph.Paint;
end;

procedure TSimulationForm.simulationClockTimer(Sender: TObject);
var CurrentSimData : TSimData;
begin
	CurrentSimData := _localSim.RunStep;
	PendulumView1.Angle := CurrentSimData.Inclination;
	PendulumView1.AngularVelocity := -CurrentSimData.AngularVelocity;
	
	InclinationGraph.DrawPoint(CurrentSimData.Time, rad2deg(CurrentSimData.Inclination));
	AngularVelocityGraph.DrawPoint(CurrentSimData.Time, CurrentSimData.AngularVelocity);
end;

procedure TSimulationForm.Label3Click(Sender: TObject);
begin
 //EnergyGraph.Visible := not //EnergyGraph.Visible;
end;

procedure TSimulationForm.Label4Click(Sender: TObject);
begin
AngularVelocityGraph.Visible := not AngularVelocityGraph.Visible;
end;

procedure TSimulationForm.Label2Click(Sender: TObject);
begin
InclinationGraph.Visible := not InclinationGraph.Visible;
end;

procedure TSimulationForm.PendulumView1RequestPause(Sender: TObject);
var mbReply : integer;
begin
	if not _paused then
	begin
        SetPaused;
		//Ask the user whether to pause
		mbReply := Application.MessageBox('Are you sure you want to pause this simulation?', 'PendulumSimulator', MB_ICONEXCLAMATION+MB_YESNO);
		if mbReply = IDNO then
		PlaySim;
	end;
end;

procedure TSimulationForm.PendulumView1AngleChanged(Sender: TObject);
begin
	edInclination.Text := rad2degRS(PendulumView1.Angle);
        StatusBar1.Panels[1].Text := 'Reset simulation for changes to take effect';
end;

procedure TSimulationForm.Button1Click(Sender: TObject);
begin
       InclinationGraph.StartTime := 0;
       InclinationGraph.Initialise;

       AngularVelocityGraph.StartTime := 0;
       AngularVelocityGraph.Initialise;
end;

procedure TSimulationForm.RunSimulation1Click(Sender: TObject);
begin
     if _paused then PlaySim;
end;

procedure TSimulationForm.PauseSimulation1Click(Sender: TObject);
var mbReply : integer;
begin
    tbtnStopSimClick(Sender);
end;

procedure TSimulationForm.ResetSimulation1Click(Sender: TObject);
begin
    tbtnResetSimClick(Sender);
end;

procedure TSimulationForm.SimulationSettings1Click(Sender: TObject);
begin
    tbtnSettingsPaneClick(Sender);
end;

procedure TSimulationForm.edInclinationChange(Sender: TObject);
begin
StatusBar1.Panels[1].Text := 'Reset simulation for changes to take effect';
end;

procedure TSimulationForm.edDampingFactorMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
    StatusBar1.Panels[1].Text := 'Set the damping factor of the pendulum simulation';
end;

procedure TSimulationForm.edStringLengthMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
StatusBar1.Panels[1].Text := 'Set the pendulums string length';
end;

procedure TSimulationForm.chkDampingMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
StatusBar1.Panels[1].Text := 'Enable simulation of damping (using damping coefficient set in Pendulum Properties)';
end;

procedure TSimulationForm.edGravityMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
begin
StatusBar1.Panels[1].Text := 'Set the gravitational field strength in the simulation environment';
end;

procedure TSimulationForm.edSimTimeStepMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
StatusBar1.Panels[1].Text := 'Set the minimum time step for the calculations (>40ms)';
end;

procedure TSimulationForm.edBobMassMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
begin
StatusBar1.Panels[1].Text := 'Set the bob mass of the pendulum';
end;

procedure TSimulationForm.edInclinationMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
StatusBar1.Panels[1].Text := 'Set the inclination of the pendulum (Requires Reset)';
end;

procedure TSimulationForm.edAngularVelocityMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
StatusBar1.Panels[1].Text := 'Set the angular velocity of the pendulum (Requires Reset)';
end;

procedure TSimulationForm.edRefreshRateMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
   StatusBar1.Panels[1].Text := 'Rate at which screen is redrawn (25fps nominal), lower for slower systems';
   
end;

procedure TSimulationForm.Button1MouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
begin
StatusBar1.Panels[1].Text := 'Reset all graphs to initial state';
end;

procedure TSimulationForm.Button2MouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
begin
StatusBar1.Panels[1].Text := 'Run a quick test to determine optimum graph scales';
end;

procedure TSimulationForm.PendulumView1MouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
StatusBar1.Panels[1].Text := 'Click and drag to set initial angle. Press Ctrl and drag with the Left Mouse Button to adjust the origin of the pendulum.';
end;

procedure TSimulationForm.CalculateOptimumScales;
var
maxSimData : TSimData;
xScale: integer;
mbResult : integer;
begin
	StatusBar1.Panels[1].Text := 'Please Wait... Calculating optimum graph scales';
	
	maxSimData := _localSim.GetMaxes(_scalingIterCount);
	
	//Set time scale at 5 units per graph
	
	//Inclination Graph Scale;
	//Set X axis Origin;
        try
	with InclinationGraph do
	begin
        AutoScale := false;
		SetOrigin(AxisOrigin.X,ClientRect.Bottom div 2);
		SetScale((ClientRect.Right-40)/2/10, (ClientRect.Bottom - 20)/2/rad2deg(maxSimData.Inclination));

		Initialise;
	end;

	with AngularVelocityGraph do
	begin
                AutoScale := false;
		SetOrigin(AxisOrigin.X,ClientRect.Bottom div 2);
		SetScale((ClientRect.Right-40)/2/10, (ClientRect.Bottom - 20)/2/maxSimData.AngularVelocity);
                PendulumView1.AngularVScale := 60/maxSimData.AngularVelocity;
		Initialise;
	end;
        except
                on E : Exception do
                begin
                    	mbResult := Application.MessageBox(PChar('Description: '+E.Message), PChar('Exception Raised: '+E.ClassName), MB_OK+MB_ICONEXCLAMATION);
                end;
        end;

        StatusBar1.Panels[1].Text := 'Done...';
end;

procedure TSimulationForm.Button2Click(Sender: TObject);
begin
CalculateOptimumScales;

end;

function TSimulationForm.GetAppPath : String;
var AppPath: String;
begin


GetDir( 0,AppPath);
GetAppPath := AppPath;
end;

procedure TSimulationForm.tbtnHelpClick(Sender: TObject);
begin
//WebBrowser1.Navigate(GetAppPath + ROOTWEB + HELP);
	//Toggle the help pane visible or not
	Panel5.Visible := not Panel5.Visible;
	tbtnHelp.Down := Panel5.Visible;
end;

procedure TSimulationForm.tbtnBackClick(Sender: TObject);
begin
WebBrowser1.GoBack;

end;

procedure TSimulationForm.tbtnHomeClick(Sender: TObject);
begin
    WebBrowser1.Navigate(GetAppPath + ROOTWEB + HOMEPAGE);
end;

procedure TSimulationForm.InclinationGraphWhatsThis(Sender: TObject);
begin
WebBrowser1.Navigate(GetAppPath + ROOTWEB + INCLINATIONGRAPHFILE);
end;

procedure TSimulationForm.AngularVelocityGraphWhatsThis(Sender: TObject);
begin
WebBrowser1.Navigate(GetAppPath + ROOTWEB + ANGULARVGRAPHFILE);
end;

procedure TSimulationForm.Help2Click(Sender: TObject);
begin
     WebBrowser1.Navigate(GetAppPath + ROOTWEB + HELP);
end;

procedure TSimulationForm.Exit1Click(Sender: TObject);
begin
     Application.Terminate;
end;

procedure TSimulationForm.Close1Click(Sender: TObject);
begin
//MainForm.Close;
end;

procedure TSimulationForm.tbtnNewClick(Sender: TObject);
var MyForm : TSimulationForm;
begin
MyForm := TSimulationForm.Create(Application);
MyForm.Show;
end;

procedure TSimulationForm.NewSimulation1Click(Sender: TObject);
begin
      tbtnNewClick(Sender);
end;

procedure TSimulationForm.Button3Click(Sender: TObject);
begin
tbtnResetSimClick(Sender);
end;

procedure TSimulationForm.edSimTimeStepChange(Sender: TObject);
begin
try
	_localSim.TimeStep := strToFloat(edSimTimeStep.Text)/1000;
	edSimTimeStep.Font.Color := clWindowText;
except
	on E:Exception do
	begin
		edSimTimeStep.Font.Color := clRed;
	end;
end;
end;

procedure TSimulationForm.edGravityChange(Sender: TObject);
begin
try
		_localSim.Gravity := strToFloat(edGravity.Text);
	edGravity.Font.Color := clWindowText;
except
	on E:Exception do
	begin
		edGravity.Font.Color := clRed;
	end;
end;
end;

procedure TSimulationForm.edStringLengthChange(Sender: TObject);
begin
try
	_pendulum.StringLength := strToFloat(edStringLength.Text);
	edStringLength.Font.Color := clWindowText;
except
	on E:Exception do
	begin
		edStringLength.Font.Color := clRed;
	end;
end;
end;

procedure TSimulationForm.edBobMassChange(Sender: TObject);
begin
try
	_pendulum.BobMass := strToFloat(edBobMass.Text)/1000;
	edBobMass.Font.Color := clWindowText;
except
	on E:Exception do
	begin
		edBobMass.Font.Color := clRed;
	end;
end;
end;

procedure TSimulationForm.edDampingFactorChange(Sender: TObject);
begin
try
	_localSim.DampingFactor := strToFloat(edDampingFactor.Text);
	TrackBar1.Position := round(_localSim.DampingFactor*20);
	edDampingFactor.Font.Color := clWindowText;
except
	on E:Exception do
	begin
		edDampingFactor.Font.Color := clRed;
	end;
end;

end;

procedure TSimulationForm.chkDampingClick(Sender: TObject);
begin
//
_localSim.DampingEnabled := chkDamping.Checked;
end;

procedure TSimulationForm.edRefreshRateChange(Sender: TObject);
begin
//
end;

procedure TSimulationForm.tbnQuickHelpClick(Sender: TObject);
begin
WebBrowser1.Navigate(GetAppPath + ROOTWEB + HELP);
end;

procedure TSimulationForm.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
Action:=caFree;
end;

end.
